package com.feonix.common.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;

public class FileUtil {

	private static final Log logger = LogFactory.getLog(FileUtil.class);
	public static final long ONE_KB = 1024L;
	public static final long ONE_MB = 1048576L;
	public static final long ONE_GB = 1073741824L;
	public static final String[] EXCEL_FILE = { "xls" };

	public static final String[] WORD_FILE = { "doc" };

	/**
	 * 复制文件
	 * 
	 * @param srcPath
	 *            - 源文件
	 * @param destPath
	 *            - 目标文件
	 * @return
	 */
	public static boolean copyFile(String srcPath, String destPath) {
		if ((StringUtil.isNotEmpty(srcPath)) && (StringUtil.isNotEmpty(destPath))) {
			return copyFile(new File(srcPath), new File(destPath), false);
		}
		return false;
	}

	/**
	 * 复制文件
	 * 
	 * @param srcPath
	 *            - 源文件
	 * @param destPath
	 *            - 目标文件
	 * @return
	 */
	public static boolean copyFile(File srcPath, File destPath) {
		return copyFile(srcPath, destPath, false);
	}

	/**
	 * 移动文件
	 * 
	 * @param srcPath
	 *            源文件
	 * @param destPath
	 *            目标文件
	 * @return
	 */
	public static boolean moveFile(String srcPath, String destPath) {
		if ((StringUtil.isNotEmpty(srcPath)) && (StringUtil.isNotEmpty(destPath))) {
			return copyFile(new File(srcPath), new File(destPath), true);
		}
		return false;
	}

	/**
	 * 移动文件
	 * 
	 * @param srcPath
	 *            源文件
	 * @param destPath
	 *            目标文件
	 * @return
	 */
	public static boolean moveFile(File srcPath, File destPath) {
		return copyFile(srcPath, destPath, true);
	}

	/**
	 * 
	 * @param srcPath
	 *            源文件
	 * @param destPath
	 *            目标文件
	 * @param paramBoolean
	 *            是否删除原文件
	 * @return
	 */
	private static boolean copyFile(File srcPath, File destPath, final boolean isDelete) {
		boolean result = false;
		try {
			FileUtils.copyFile(srcPath, destPath);
			if (isDelete) {
				result = srcPath.delete();
			} else {
				result = true;
			}
		} catch (Exception exception) {
			logger.error("copyFile(File, File):" + exception.getMessage());
		}
		return result;
	}

	/**
	 * 拷贝文件到目录
	 * 
	 * @param srcFile
	 *            源文件
	 * @param destDir
	 *            目标目录
	 * @return
	 */
	public static boolean copyFileToDirectory(File srcFile, File destDir) {
		boolean isSuccess = false;
		try {
			FileUtils.copyFileToDirectory(srcFile, destDir);
			isSuccess = true;
		} catch (Exception exception) {
			isSuccess = false;
			logger.error("copyFileToDirectory(File, File):" + exception.getMessage());
		}
		return isSuccess;
	}

	/**
	 * 拷贝目录，将 a 下的所有文件拷贝到 b目录下
	 * 
	 * @param srcPath
	 *            源目录
	 * @param destDir
	 *            目标目录
	 * @return
	 */
	public static boolean copyDirectory(String srcPath, String destDir) {
		if ((StringUtil.isNotEmpty(srcPath)) && (StringUtil.isNotEmpty(destDir))) {
			return copyDirectory(new File(srcPath), new File(destDir));
		}
		return false;
	}

	/**
	 * 拷贝目录，将 a 下的所有文件拷贝到 b目录下
	 * 
	 * @param srcPath
	 *            源目录
	 * @param destDir
	 *            目标目录
	 * @return
	 */
	public static boolean copyDirectory(File srcPath, File destDir) {
		boolean isSuccess = false;
		try {
			FileUtils.copyDirectory(srcPath, destDir);
			isSuccess = true;
		} catch (Exception exception) {
			logger.error("copyDirectory(File, File):" + exception.getMessage());
			isSuccess = false;
		}
		return isSuccess;
	}

	/**
	 * 拷贝目录到另一个目录下，将 a目录整个拷贝到 b目录下
	 * 
	 * @param srcDir
	 *            源目录
	 * @param destDir
	 *            目标目录
	 * @return
	 */
	public static boolean copyDirectoryToDirectory(String srcDir, String destDir) {
		if ((StringUtil.isNotEmpty(srcDir)) && (StringUtil.isNotEmpty(destDir))) {
			return copyDirectoryToDirectory(new File(srcDir), new File(destDir));
		}
		return false;
	}

	/**
	 * 拷贝目录到另一个目录下，将 a目录整个拷贝到 b目录下
	 * 
	 * @param srcPath
	 * @param destPath
	 * @return
	 */
	public static boolean copyDirectoryToDirectory(File srcPath, File destPath) {
		boolean isSuccess = false;
		try {
			FileUtils.copyDirectoryToDirectory(srcPath, destPath);
			isSuccess = true;
		} catch (Exception exception) {
			isSuccess = false;
			logger.error("copyDirectoryToDirectory(File, File)" + exception.getMessage());
		}
		return isSuccess;
	}

	/**
	 * 删除文件
	 * 
	 * @param srcPath
	 *            一个文件路径
	 * @return
	 */
	public static boolean deleteFile(String srcPath) {
		if (StringUtil.isNotEmpty(srcPath)) {
			return deleteFile(new File(srcPath));
		}
		return false;
	}

	/**
	 * 删除文件
	 * 
	 * @param srcFile
	 *            一个文件对象
	 * @return
	 */
	public static boolean deleteFile(File srcFile) {
		boolean bool = false;
		bool = srcFile.delete();
		return bool;
	}

	/**
	 * 获得文件输入流
	 * 
	 * @param srcFile
	 * @return
	 */
	public static FileInputStream openInputStream(File srcFile) {
		FileInputStream fileInputStream = null;
		try {
			fileInputStream = FileUtils.openInputStream(srcFile);
		} catch (Exception exception) {
			logger.error("获得FileInputStream失败");
		}
		return fileInputStream;
	}

	/**
	 * 获得文件输出流
	 * 
	 * @param srcFile
	 * @return
	 */
	public static FileOutputStream openOutputStream(File srcFile) {
		FileOutputStream fileOutputStream = null;
		try {
			fileOutputStream = FileUtils.openOutputStream(srcFile);
		} catch (Exception exception) {
			logger.error("获得FileOutputStream失败");
		}
		return fileOutputStream;
	}

	/**
	 * 删除多个文件
	 * 
	 * @param files
	 *            文件集合
	 * @return
	 */
	public static boolean deleteFiles(Collection<File> files) {
		boolean isSuccess = false;
		for (File file : files) {
			isSuccess = file.delete();
			if (!isSuccess) {
				break;
			}
		}
		return isSuccess;
	}

	/**
	 * 删除目录
	 * 
	 * @param scrDir
	 *            目标目录
	 * @return
	 */
	public static boolean deleteDirectory(File scrDir) {
		boolean isSuccess = false;
		try {
			FileUtils.deleteDirectory(scrDir);
			isSuccess = true;
		} catch (Exception exception) {
			isSuccess = false;
			logger.error("deleteDir(File)" + exception.getMessage());
		}
		return isSuccess;
	}

	/**
	 * 清空目录
	 * 
	 * @param paramFile
	 *            目标目录
	 * @return
	 */
	public static boolean cleanDirectory(File scrDir) {
		boolean isSuccess = false;
		try {
			FileUtils.cleanDirectory(scrDir);
			isSuccess = true;
		} catch (Exception exception) {
			isSuccess = false;
			logger.error("cleanDirectory(File)" + exception.getMessage());
		}
		return isSuccess;
	}

	/**
	 * 得到目录的大小
	 * 
	 * @param paramFile
	 *            目录路径
	 * @return
	 */
	public static long sizeOfDirectory(File srcDir) {
		return FileUtils.sizeOfDirectory(srcDir);
	}

	/**
	 * 写文件操作
	 * 
	 * @param file
	 * @param data
	 * @param encoding
	 * @return
	 */
	public static boolean writeStringToFile(File file, String data, String encoding) {
		boolean isSuccess = false;
		try {
			if (file.getName().contains("")) {
				return false;
			}
			if ((encoding == null) || (encoding.trim().length() == 0)) {
				encoding = "utf-8";
			}
			logger.debug("writeStringToFile:" + file.getPath());
			FileUtils.writeStringToFile(file, data, encoding);
			isSuccess = true;
		} catch (Exception exception) {
			logger.error("writeStringToFile(File,String,String)" + exception.getMessage());
		}
		return isSuccess;
	}

	/**
	 * 写文件操作
	 * 
	 * @param filePath
	 * @param data
	 * @return
	 */
	public static boolean writeStringToFile(String filePath, String data) {
		boolean bool = false;
		if (StringUtil.isNotEmpty(filePath)) {
			File file = new File(filePath);
			bool = writeStringToFile(file, data, null);
		}
		return bool;
	}

	/**
	 * 写文件操作
	 * 
	 * @param file
	 * @param data
	 * @return
	 */
	public static boolean writeStringToFile(File file, String data) {
		return writeStringToFile(file, data, null);
	}

	/**
	 * 将inputStream写入文件
	 * 
	 * @param file
	 * @param inputStream
	 * @return
	 */
	public static boolean writeInputStreamToFile(File file, InputStream inputStream) {
		boolean isSuccess = false;
		OutputStream ops = null;
		try {
			if (file.getName().contains("")) {
				return false;
			}
			ops = new FileOutputStream(file);
			IOUtils.write(IOUtils.toByteArray(inputStream), ops);
			isSuccess = true;
		} catch (Exception exception) {
			logger.error("writeInputStreamToFile error", exception);
		} finally {
			IOUtils.closeQuietly((OutputStream) ops);
			IOUtils.closeQuietly(inputStream);
		}
		return isSuccess;
	}

	/**
	 * 按照行读取文件
	 * 
	 * @param file
	 * @param charset
	 * @return
	 */
	public static List<String> readLines(File file, String charset) {
		try {
			if ((charset == null) || (charset.trim().length() == 0)) {
				return FileUtils.readLines(file, "utf-8");
			}
			return FileUtils.readLines(file, charset);
		} catch (Exception exception) {
			logger.error("readLines(File,String)" + exception.getMessage());
		}
		return null;
	}

	/**
	 * 按照行读取文件 默认字符集为utf8
	 * 
	 * @param file
	 * @return
	 */
	public static List<String> readLines(File file) {
		return readLines(file, null);
	}

	/**
	 * 读取文件为字符串
	 * 
	 * @param file
	 * @param charset
	 * @return
	 */
	public static String readFileToString(File file, String charset) {
		try {
			if ((charset == null) || (charset.trim().length() == 0)) {
				return FileUtils.readFileToString(file, "utf-8");
			}
			return FileUtils.readFileToString(file, charset);
		} catch (Exception exception) {
			logger.error("readLines(File,String)" + exception.getMessage());
		}
		return null;
	}

	/**
	 * 读取文件为字符串 默认编码为 utf-8
	 * 
	 * @param file
	 * @return
	 */
	public static String readFileToString(File file) {
		return readFileToString(file, null);
	}

	/**
	 * 读取文件为字符串 默认编码为 utf-8
	 * 
	 * @param path
	 * @return
	 */
	public static String readFileToString(String path) {
		if (StringUtil.isNotEmpty(path)) {
			return readFileToString(new File(path), null);
		}
		return null;
	}

	/**
	 * 读取文件为字符串
	 * 
	 * @param path
	 * @param charset
	 * @return
	 */
	public static String readFileToString(String path, String charset) {
		if (StringUtil.isNotEmpty(path)) {
			return readFileToString(new File(path), charset);
		}
		return null;
	}

	/**
	 * 过滤文件夹下的文件
	 * 
	 * @param dir
	 * @param fileType
	 * @param recursive
	 * @return
	 */
	public static List<File> filterFiles(File dir, String[] fileType, boolean recursive) {
		List localList = (List) FileUtils.listFiles(dir, fileType, recursive);
		return localList;
	}

	/**
	 * 读取文件成字节数组数组
	 * 
	 * @param filePath
	 * @return
	 */
	public static byte[] readFileToByteArray(String filePath) {
		byte[] arrayOfByte = null;
		try {
			if (StringUtil.isNotEmpty(filePath))
				arrayOfByte = FileUtils.readFileToByteArray(new File(filePath));
		} catch (Exception exception) {
			logger.error("文件未找到" + exception.getMessage());
		}
		return arrayOfByte;
	}

	/**
	 * 读取文件成字节数组数组
	 * 
	 * @param file
	 * @return
	 */
	public static byte[] readFileToByteArray(File file) {
		byte[] arrayOfByte = null;
		try {
			arrayOfByte = FileUtils.readFileToByteArray(file);
		} catch (Exception exception) {
			logger.error("文件未找到" + exception.getMessage());
		}
		return arrayOfByte;
	}

	/**
	 * 将字节数组写成文件
	 * 
	 * @param filePath
	 * @param bytes
	 */
	public static void writeByteArrayToFile(String filePath, byte[] bytes) {
		if (StringUtil.isNotEmpty(filePath)) {
			if (filePath.contains("")) {
				return;
			}
			writeByteArrayToFile(new File(filePath), bytes);
		}
	}

	/**
	 * 将字节数组写成文件
	 * 
	 * @param file
	 * @param bytes
	 */
	public static void writeByteArrayToFile(File file, byte[] bytes) {
		try {
			if (file.getName().contains("")) {
				return;
			}
			FileUtils.writeByteArrayToFile(file, bytes);
		} catch (Exception exception) {
			logger.error("写入文件为成功" + exception.getMessage());
		}
	}

	/**
	 * 判断文件夹是否存在
	 * 
	 * @param file
	 * @param isCreate
	 * @return
	 */
	public static boolean isDirExsit(File file, boolean isCreate) {
		boolean isSuccess = false;
		if ((file.isDirectory()) && (file.exists())) {
			isSuccess = true;
		} else if (isCreate) {
			file.mkdirs();
		}
		return isSuccess;
	}

	/**
	 * 创建文件，如果存在则放弃
	 * 
	 * @param file
	 */
	public static void createFile(File file) {
		if ((file == null) || (file.exists()))
			return;
		try {
			FileUtils.touch(file);
		} catch (Exception exception) {
			logger.error("createFile error", exception);
		}
	}

	/**
	 * 创建目录
	 * 
	 * @param path
	 */
	public static void createDir(String path) {
		if (StringUtil.isNotEmpty(path)) {
			File file = new File(path);
			if (!(file.exists()))
				file.mkdirs();
		}
	}

	/**
	 * 获得文件的类型（后缀）
	 * 
	 * @param str
	 * @return
	 */
	public static String getType(String str) {
		String str1 = null;
		int i = str.indexOf("?");
		String str2 = str;
		if (i > -1) {
			str2 = str2.substring(0, i);
		}
		i = str2.lastIndexOf(".");
		if (i > -1) {
			str1 = str2.substring(i + 1, str2.length()).toLowerCase();
		}
		return str1;
	}

	/**
	 * 读取jar包文件
	 * 
	 * @param file
	 * @return
	 */
	public static Map<String, byte[]> readContentFromJar(File file) {
		HashMap<String, byte[]> content = null;
		JarFile jarFile = null;
		InputStream inputStream = null;
		try {
			content = new HashMap<String, byte[]>();
			jarFile = new JarFile(file);
			Enumeration<JarEntry> enumeration = jarFile.entries();
			JarEntry jarEntry = null;
			while (enumeration.hasMoreElements()) {
				jarEntry = enumeration.nextElement();
				inputStream = jarFile.getInputStream(jarEntry);
				content.put(jarEntry.getName(), IOUtils.toByteArray(inputStream));
				IOUtils.closeQuietly(inputStream);
			}
		} catch (Exception exception1) {
			logger.error("读取jar包错误", exception1);
		} finally {
			IOUtils.closeQuietly(inputStream);
			if (jarFile != null) {
				try {
					jarFile.close();
				} catch (Exception exception3) {
					logger.warn("关闭jar读取错误了。");
				}
			}
		}
		return content;
	}

	/**
	 * 写入jar包文件
	 * 
	 * @param file
	 * @param map
	 * @return
	 */
	public static boolean writeContentToJar(File file, Map<String, byte[]> map) {
		boolean isSuccess = false;
		JarOutputStream jarOutputStream = null;
		try {
			jarOutputStream = new JarOutputStream(new FileOutputStream(file));
			Iterator<String> iterator = map.keySet().iterator();
			JarEntry jarEntry = null;
			String str = null;
			while (iterator.hasNext()) {
				str = iterator.next();
				jarEntry = new JarEntry(str);
				jarOutputStream.putNextEntry(jarEntry);
				jarOutputStream.write(map.get(str));
			}
			jarOutputStream.flush();
			isSuccess = true;
		} catch (FileNotFoundException fileNotFoundException) {
			logger.error("文件没找到", fileNotFoundException);
		} catch (Exception exception1) {
			logger.error("JarOutputStream读取异常", exception1);
		} finally {
			if (jarOutputStream != null) {
				try {
					jarOutputStream.close();
				} catch (Exception exception4) {
					logger.warn("关闭JarOutputStream错误了。");
				}
			}
		}
		return isSuccess;
	}

	/**
	 * 将对象序列化到硬盘
	 * 
	 * @param object
	 * @param path
	 */
	public static void writeObject(Object object, String path) {
		FileOutputStream fileOutputStream = null;
		ObjectOutputStream objectOutputStream = null;
		try {
			fileOutputStream = new FileOutputStream(path);
			objectOutputStream = new ObjectOutputStream(fileOutputStream);
			objectOutputStream.writeObject(object);
		} catch (Exception exception1) {
			logger.error("storeObject error", exception1);
		} finally {
			if (objectOutputStream != null)
				try {
					objectOutputStream.close();
				} catch (Exception exception4) {
				}
			if (fileOutputStream != null)
				try {
					fileOutputStream.close();
				} catch (Exception exception5) {
				}
		}
	}

	/**
	 * 将序列化到硬盘的对象读取成对象
	 * 
	 * @param path
	 * @return
	 */
	public static <T> T readObject(String path) {
		FileInputStream fileInputStream = null;
		ObjectInputStream objectInputStream = null;
		Object object1 = null;
		try {
			fileInputStream = new FileInputStream(path);
			objectInputStream = new ObjectInputStream(fileInputStream);
			object1 = objectInputStream.readObject();
		} catch (Exception exception1) {
			logger.error("readToDocument error", exception1);
		} finally {
			if (objectInputStream != null)
				try {
					objectInputStream.close();
				} catch (Exception localException4) {
				}
			if (fileInputStream != null)
				try {
					fileInputStream.close();
				} catch (Exception localException5) {
				}
		}
		return (T) object1;
	}

	/**
	 * 获得文件的类型名称
	 * 
	 * @param file
	 * @return
	 */
	public static String getExtension(File file) {
		String str = file.getName();
		return getExtension(str);
	}

	/**
	 * 获得文件的类型名称
	 * 
	 * @param name
	 * @return
	 */
	public static String getExtension(String file) {
		String str = null;
		if (StringUtil.isNotEmpty(file)) {
			if (file.contains("?")) {
				String[] arrayOfString = file.split("\\?");
				if (arrayOfString.length > 0) {
					file = arrayOfString[0];
				}

			}

			str = FilenameUtils.getExtension(file);
			if (StringUtil.isNotEmpty(str)) {
				str = str.toLowerCase();
			}
		}
		return str;
	}

	/**
	 * 获取不带文件后缀的文件名
	 * 
	 * @param name
	 * @return
	 */
	public static String getSimpleName(File name) {
		String str = name.getName();
		return getSimpleName(str);
	}

	/**
	 * 获得mimetype
	 * 
	 * @param path
	 * @return
	 */
	public static String getSimpleName(String path) {
		String str = null;
		if (StringUtil.isNotEmpty(path)) {
			str = FilenameUtils.getBaseName(path);
		}
		return str;
	}

}
